#include "FastCGICache.h"

FCGI_Cache::FCGI_Cache() :
data(NULL), size(NULL) {}

FCGI_Cache::FCGI_Cache(const FCGI_Cache &cache) {
	this->Push(cache.data, cache.size);
}

FCGI_Cache::~FCGI_Cache() {
	this->Flush();
}

void *FCGI_Cache::Data() {
	return this->data;
}

u_int FCGI_Cache::Size() {
	return this->size;
}

bool FCGI_Cache::Empty() {
	if (this->size == NULL) 
		return true;
	return false;
}

// 压入
void FCGI_Cache::Push(void *data, u_int size) {
	if (this->data == NULL || this->size == NULL) {
		this->size = size;
		this->data = malloc(size);
		memcpy(this->data, data, size);
	} else {
		this->size += size;
		this->data = realloc(this->data, this->size);
		memcpy((char *)(this->data) + this->size - size, data, size);
	}
}

// 弹出
void FCGI_Cache::Pop(void *data, u_int size, bool direction) {
	if (this->data == NULL || this->size == NULL) {
		data = NULL;
	} else if (this->size < size) {
		memcpy(data, (char *)this->data, this->size);
		this->Flush();
	} else {
		this->size -= size;

		if (direction) {
			memcpy(data, (char *)(this->data) + this->size, size);
		} else {
			memcpy(data, this->data, size);
			memcpy(this->data, (char *)(this->data) + size, this->size);
		}
		
		if (this->size == NULL)
			this->Flush();
		else
			this->data = realloc(this->data, this->size);
	}
}

void FCGI_Cache::Pop(FCGI_Cache *data, u_int size, bool direction) {
	void *localData = malloc(size);
	this->Pop(localData, size, direction);
	data->Push(localData, size);
	free(localData);
}

// 寻找
u_int FCGI_Cache::Find(void *data, u_int size) {
	if (this->size < size)
		return false;

	for (u_int i = 0; i < this->size - size + 1; i++) {
		if (memcmp((char *)this->data + i, data, size) == 0) {
			return i;
		}
	}

	return -1;
}

// 清空
void FCGI_Cache::Flush() {
	if (this->data == NULL || this->size == NULL) {
		return;
	} else {
		free(this->data);
	
		this->data = NULL;
		this->size = NULL;
	}
}